package com.itlong.cloud.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.app.AppGetProjectDTO;
import com.itlong.cloud.POJO.DTO.app.AppTouristDTO;
import com.itlong.cloud.POJO.PO.AppUserProjectPO;
import com.itlong.cloud.POJO.PO.RoomInfoPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.*;
import com.itlong.cloud.POJO.VO.property.PropertyProjectBuildSimpleInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectRoomInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectRoomSimpleInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectUnitSimpleInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppBuildDao;
import com.itlong.cloud.app.dao.IAppProjectDao;
import com.itlong.cloud.app.dao.IAppRoomDao;
import com.itlong.cloud.app.dao.IAppUnitDao;
import com.itlong.cloud.app.service.IAppProjectService;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.property.dao.IPropertyBuildInfoDao;
import com.itlong.cloud.property.dao.IPropertyRoomInfoDao;
import com.itlong.cloud.property.dao.IPropertyUnitInfoDao;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.encrypt.Md5;
import com.itlong.cloud.utils.location.LocationUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 * APP端项目信息服务层接口实现类
 * </desc>
 *
 * @createDate 2017/09/29
 */
@Service
public class AppProjectServiceImpl implements IAppProjectService {


    @Autowired
    IAppProjectDao iAppProjectDao;

    @Autowired
    IAppBuildDao iAppBuildDao;

    @Autowired
    IPropertyBuildInfoDao iPropertyBuildInfoDao;

    @Autowired
    IAppUnitDao iAppUnitDao;

    @Autowired
    IPropertyUnitInfoDao iPropertyUnitInfoDao;

    @Autowired
    IAppRoomDao iAppRoomDao;

    @Autowired
    IPropertyRoomInfoDao iPropertyRoomInfoDao;

    //当dataSource为1时，在物业人员信息列表中不展示该用户
    private static final int DATA_SOURCE = 1;

    private static final int VISITOR_TYPE = 4;

    private static final String VISITOR_NAME = "访客";

    /**
     * <desc>
     * 根据城市名称获取城市id
     * </desc>
     *
     * @param cityName
     * @return
     * @author Jiaqi.X
     * @createDate 2020/05/28
     */
    public String getCityIdByCityName(String cityName) {
        return iAppProjectDao.getCityIdByCityName(cityName);
    }

    /**
     * <desc>
     * 根据城市ID获取启用状态的项目信息（项目编号与项目名称）
     * </desc>
     *
     * @param appGetProjectDTO   app获取项目参数DTO
     * @return
     * @throws Exception
     * @author cuiduanwu
     * @createDate 2017/9/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<AppDistinctProjectVO> getProjectsInCity(AppGetProjectDTO appGetProjectDTO) throws Exception {

        List<AppDistinctProjectVO> distinctProjectVOList = iAppProjectDao.getChilds(appGetProjectDTO.getCityId());
        Map<String, Object> param = new HashMap<>();
        distinctProjectVOList.forEach(item -> {
            param.put("districtId", item.getDistrictId());
            item.setProjects(iAppProjectDao.getProjectsInCity(param));
        });
        return distinctProjectVOList;
    }


    /**
     * <desc>
     * app2.0根据城市ID获取启用状态的项目信息（项目编号与项目名称）
     * </desc>
     *
     * @param cityId 城市ID
     * @return
     * @throws Exception
     * @author Qiang.S
     * @createDate 2019/06/20
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<AppProjectBuildVO> getNewProjectsInCity(String cityId) throws Exception {
        List<AppProjectBuildVO> list = new ArrayList<>();
        List<Map<String, Object>> projectInfo = iAppProjectDao.getNewProjectsInCity(cityId);
        AppProjectBuildVO vo = new AppProjectBuildVO();
        List<AppProjectBuildVO.Builds> builds = new ArrayList<>();
        for (Map<String, Object> map : projectInfo) {
            if (vo.getProjectName() != null && !vo.getProjectName().equals(map.get("projectName").toString())) {
                vo.setBuilds(builds);
                list.add(vo);
                builds = new ArrayList<>();
                vo = new AppProjectBuildVO();
            }
            vo.setProjectName(map.get("projectName").toString());
            vo.setProjectId(map.get("projectId").toString());
            AppProjectBuildVO.Builds build = new AppProjectBuildVO.Builds();
            build.setBuildId(map.get("buildId").toString());
            build.setBuildName(map.get("buildName").toString());
            builds.add(build);
        }
        if (builds.size() > 0) {
            vo.setBuilds(builds);
            list.add(vo);
        }
        return list;
    }

    /**
     * <desc>
     * app2.0根据楼栋编号获取单元和房间
     * </desc>
     *
     * @param buildId 楼栋编号
     * @return
     * @throws Exception
     * @author Qiang.S
     * @createDate 2019/06/20
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<AppProjectRoomVO> getNewProjectsUnit(String buildId) throws Exception {
        List<AppProjectRoomVO> list = new ArrayList<>();
        List<Map<String, Object>> projectInfo = iAppProjectDao.getNewProjectsUnit(buildId);
        AppProjectRoomVO vo = new AppProjectRoomVO();
        List<AppProjectRoomVO.Rooms> rooms = new ArrayList<>();
        for (Map<String, Object> map : projectInfo) {
            if (vo.getUnitName() != null && !vo.getUnitName().equals(map.get("unitName").toString())) {
                vo.setRooms(rooms);
                list.add(vo);
                rooms = new ArrayList<>();
                vo = new AppProjectRoomVO();
            }
            vo.setUnitName(map.get("unitName").toString());
            AppProjectRoomVO.Rooms room = new AppProjectRoomVO.Rooms();
            room.setRoomId(map.get("roomId").toString());
            room.setRoomName(map.get("roomName").toString());
            rooms.add(room);
        }
        if (rooms.size() > 0) {
            vo.setRooms(rooms);
            list.add(vo);
        }
        return list;
    }

    /**
     * <desc>
     * 根据国家ID获取启用状态的项目信息（项目编号与项目名称）。
     * <desc/>
     *
     * @param countryId
     * @param pageNo
     * @param pageSize
     * @return
     * @author shengen.T
     * @createDate 2018-01-03
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
    public Page<Map<String, Object>> getProjectsInCountry(String countryId, String pageNo, String pageSize) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("countryId", countryId);
        Page<Map<String, Object>> page = new Page<>();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(pageNo);

        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        page.setRows(iAppProjectDao.getProjectsInCountry(params));
        return page;
    }

    /**
     * <desc>
     * 根据项目编号获取启用状态的楼栋信息
     * </desc>
     *
     * @param projectId 项目编号
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     * @author cuiduanwu
     * @createDate 2017/9/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Page<PropertyProjectBuildSimpleInfoVO> getBuildsInProject(String projectId, String pageNo, String pageSize) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("projectId", projectId);
        Page<PropertyProjectBuildSimpleInfoVO> page = new Page<>();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(pageNo);
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        //填充返回数据集
        List<PropertyProjectBuildSimpleInfoVO> datas = iAppProjectDao.getBuildsInProject(params);
        page.setRows(datas);
        return page;
    }

    /**
     * <desc>
     * 根据楼栋ID获取启用状态的单元信息
     * </desc>
     *
     * @param buildId 楼栋ID
     * @return
     * @throws Exception
     * @createDate 2017/9/30
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Page<PropertyProjectUnitSimpleInfoVO> getUnitsInBuild(String buildId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("buildId", buildId);
        params.put("status", 1); //启用状态
        Page<PropertyProjectUnitSimpleInfoVO> page = new Page<>();
        page.getPage().setPageSize("10");
        page.getPage().setCurrentPage("1");

        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        //填充返回数据集
        List<PropertyProjectUnitSimpleInfoVO> datas = iAppProjectDao.getUnitsInBuild(params);
        page.setRows(datas);
        return page;

    }

    /**
     * <desc>
     * 根据单元ID获取启用状态的房间信息
     * </desc>
     *
     * @param unitId   单元ID
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     * @createDate 2017/10/9
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Page<PropertyProjectRoomSimpleInfoVO> getRoomsInUnit(String unitId, String pageNo, String pageSize) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("unitId", unitId);
        Page<PropertyProjectRoomSimpleInfoVO> page = new Page<>();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(pageNo);
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        //填充返回数据集
        List<PropertyProjectRoomSimpleInfoVO> datas = iAppProjectDao.getRoomInUnit(params);
        page.setRows(datas);
        return page;
    }


    /**
     * <desc>
     * 根据房间ID获取房间信息
     * </desc>
     *
     * @param roomId 房间ID
     * @return
     * @throws Exception
     * @createDate 2017/10/23
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public PropertyProjectRoomInfoVO getRoomById(String roomId) {
        RoomInfoPO roomInfoPO = new RoomInfoPO();
        roomInfoPO.setRoomId(roomId);
        return iPropertyRoomInfoDao.getOneRoomInfo(roomInfoPO);
    }


    /**
     * <desc>
     * 根据用户id获取该用户id下所有项目id集合 多个,号分隔
     * </desc>
     *
     * @param userId 用户id
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/13
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String getUserProjectIds(String userId) {
        List<String> projectIds = iAppProjectDao.getUserProjectIds(userId);
        if (projectIds != null && !projectIds.isEmpty()) {
            return StringUtil.join(projectIds.toArray(new String[projectIds.size()]), ",");
        } else {
            return "";
        }
    }


    /**
     * <desc>
     * 设置APP是否被呼叫
     * </desc>
     *
     * @param userId     用户id
     * @param isAllowApp app是否允许被呼叫 0是 1否
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/13
     */
    @Override
    public Integer setAllowApp(String userId, Integer isAllowApp, String projectId) {
        return iAppProjectDao.setAllowApp(userId, isAllowApp, projectId);
    }

    /**
     * <desc>
     * 设置电话是否被呼叫
     * </desc>
     *
     * @param projectId    项目id
     * @param userId       用户id
     * @param isAllowPhone 是否允许被呼叫 0是 1否
     * @return
     */
    @Override
    public Integer setAllowPhone(String projectId, String userId, String isAllowPhone) {
        List<String> roomIds = iAppRoomDao.getUserHouserTypeWithOneRoomIds(userId, projectId);
        //设置业主房间电话是否允许被呼叫
        if (!roomIds.isEmpty()) {
            iAppRoomDao.setUserRoomAllowPhone(roomIds.toArray(new String[roomIds.size()]), userId, isAllowPhone);
        }
        return iAppProjectDao.setAllowPhone(projectId, userId, isAllowPhone);
    }

    /**
     * <desc>
     * 设置app登录用户当前项目id
     * </desc>
     *
     * @param userId    用户id
     * @param projectId 项目id
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/28
     */
    @Override
    public Integer setCurrentProject(String userId, String projectId, String projectName) {
        return iAppProjectDao.setCurrentProject(userId, projectId, projectName);
    }

    /**
     * <desc>
     * 获取用户所有的项目id
     * </desc>
     *
     * @param userId 用户id
     * @return
     * @author Jiaqi.X
     * @createDate 2017/12/21
     */
    @Override
    public List<String> getAllProjects(String userId) {
        return iAppProjectDao.getUserAllProjectsId(userId);
    }

    /**
     * <desc>
     * 获取当前用户下所有项目的UI信息
     * </desc>
     *
     * @param projectIds 多个项目编号id，中间以逗号隔开
     * @return
     * @author JuGuang.S
     * @createDate 2018/05/24
     */
    @Override
    public List<AppGetProjectUiVO> getProjectIdUi(String projectIds, String deviceType) {
        return iAppProjectDao.getProjectIdUi(StringHandlerUtil.splitString(projectIds), deviceType);
    }

    /**
     * <desc>
     * 获取用户当前项目下的推送消息
     * </desc>
     *
     * @return 当前项目下的推送消息
     * @createDate 2019/05/30
     * @author wangzhi
     */
    @Override
    public Map<String, Object> getMessageBox(String projectId, String pageNum, String msgType, String userId, String url, String version) throws Exception {
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        params.put("projectId", projectId);
        params.put("msgType", msgType);
        params.put("userId", userId);
        // 分页索引
        if (Integer.parseInt(pageNum) > 0) {
            params.put("startSlip", (Integer.parseInt(pageNum) - 1) * 15);
        } else {
            params.put("startSlip", 0);
        }
        // 分页记录数
        params.put("pageSize", 15);
        // 消息类型
        params.put("propertyType", 5);
        // 未读缴费通知消息条数
        Integer unPayCount = iAppProjectDao.getMsgCount(params);
        data.put("unPayCount", unPayCount.toString());
        // 未读小区通知条数
        Integer unReadCount = iAppProjectDao.getPropertyPushCount(params);
        data.put("unReadCount", unReadCount.toString());
        // 未读系统消息条数
        params.put("version", version);
        Integer unSysCount = iAppProjectDao.getSysCount(params);
        data.put("unSysCount", unSysCount.toString());
        // 当前只有缴费通知
        List<AppMessageBoxVO> msgAry = null;
        if ("1".equals(msgType)) {
            params.put("propertyType", 5);
            // 计算总页数
            Integer allCount = iAppProjectDao.getAllPayCount(params);
            data.put("totalNum", allCount % 15 == 0 ? allCount / 15 : allCount / 15 + 1);
            // 查询欠费消息分页数据
            msgAry = iAppProjectDao.getMsgPage(params);
            // 1.8.5版本先注掉，1.8.6合并代码后打开注释
        } else if ("0".equals(msgType)) {
            // 小区通知
            // 计算总页数
            Integer allCount = iAppProjectDao.getAllPropertyPushCount(params);
            data.put("totalNum", allCount % 15 == 0 ? allCount / 15 : allCount / 15 + 1);
            msgAry = iAppProjectDao.getPropertyPushPage(params);
        } else if ("2".equals(msgType)) {
            // 系统消息
            // 计算总页数
            Integer allCount = iAppProjectDao.getAllSysPushCount(params);
            data.put("totalNum", allCount % 15 == 0 ? allCount / 15 : allCount / 15 + 1);
            msgAry = iAppProjectDao.getSysPage(params);
        }
        // 消息分页数据
        if (msgAry == null) {
            data.put("msgAry", new ArrayList<>());
        } else {
            if (!"1".equals(msgType)) {
                for (AppMessageBoxVO messageBoxVO : msgAry) {
                    messageBoxVO.setUrl(url + "pushInfoId=" + messageBoxVO.getMsgId());
                }
            }
            data.put("msgAry", msgAry);
        }
        return data;
    }

    /**
     * <desc>
     * 用户读取新消息
     * </desc>
     *
     * @param msgId 消息id
     * @return 1读取成功，0失败
     * @createDate 2019/05/30
     * @author wangzhi
     */
    @Override
    public Integer readNewMsg(String msgId, String userId) throws Exception {
        Integer row = iAppProjectDao.readNewMsg(msgId);
        if (row < 1) { // 更新property_info表无效，读取的消息为push_info表中的数据
            // 1.8.5版本先注掉，1.8.6合并代码后打开注释
            iAppProjectDao.deleteUserRead(msgId, userId);
            iAppProjectDao.readPushMsg(msgId, userId);
        }
        return 1;
    }

    /**
     * <desc>
     * 上传常用楼层
     * </desc>
     *
     * @param projectId       项目编号
     * @param deviceUnique    设备序列号
     * @param loadDeviceOrder 常用楼层名称
     * @param userId          用户id
     * @return 1成功，0失败
     * @author wangzhi
     * @createDate 2019/10/08
     */
    @Override
    public Integer uploadChoiceFloor(String projectId, String deviceUnique, String loadDeviceOrder, String userId, String loadPublicOrder) throws Exception {

        String controllerByElevator = iAppProjectDao.getControllerByElevator(deviceUnique);
        if (controllerByElevator != null) {
            List<String> uniques = iAppProjectDao.getByControllerDeviceUnique(controllerByElevator);

            for (String Unique : uniques) {
                String naturalFloor=null;
                if ("x".equals(loadDeviceOrder)){
                     naturalFloor="x";
                }else {
                    // 查询出权限标识natural_floor
                     naturalFloor = iAppProjectDao.getNaturalFloor(Unique, loadDeviceOrder);
                }

                // 查询用户常用楼层
                String commonFloor = iAppProjectDao.getCommonFloor(userId, projectId);

                Map<String, String> commonFloorMap;
                if (StringUtils.isNotBlank(commonFloor)) {
                    commonFloorMap = JSON.parseObject(commonFloor, HashMap.class);
                } else {
                    commonFloorMap = new HashMap<>();
                }

                commonFloorMap.put(Unique, naturalFloor);
                commonFloor = JSON.toJSONString(commonFloorMap);

                iAppProjectDao.updateCommonFloor(userId, projectId, commonFloor);
                if (loadPublicOrder != null) {
                    String PublicNaturalFloor=null;
                    if ("x".equals(loadPublicOrder)){
                        PublicNaturalFloor="x";
                    }else {
                        // 查询出权限标识natural_floor
                        PublicNaturalFloor = iAppProjectDao.getNaturalFloor(Unique, loadPublicOrder);
                    }

                    //查询用户常用公共楼层
                    String publicFloor = iAppProjectDao.getPublicFloor(userId, projectId);

                    Map<String, String> publicFloorMap;
                    if (StringUtils.isNotBlank(publicFloor)) {
                        publicFloorMap = JSON.parseObject(publicFloor, HashMap.class);
                    } else {
                        publicFloorMap = new HashMap<>();
                    }
                    publicFloorMap.put(Unique, PublicNaturalFloor);
                    publicFloor = JSON.toJSONString(publicFloorMap);
                    iAppProjectDao.updatePublicFloor(userId, projectId, publicFloor);
                }




            }
        } else {
            String naturalFloor=null;
            if ("x".equals(loadDeviceOrder)){
                naturalFloor="x";
            }else {
                // 查询出权限标识natural_floor
                naturalFloor = iAppProjectDao.getNaturalFloor(deviceUnique, loadDeviceOrder);
            }

            // 查询用户常用楼层
            String commonFloor = iAppProjectDao.getCommonFloor(userId, projectId);
            Map<String, String> commonFloorMap;
            if (StringUtils.isNotBlank(commonFloor)) {
                commonFloorMap = JSON.parseObject(commonFloor, HashMap.class);
            } else {
                commonFloorMap = new HashMap<>();
            }
            commonFloorMap.put(deviceUnique, naturalFloor);
            commonFloor = JSON.toJSONString(commonFloorMap);

            iAppProjectDao.updateCommonFloor(userId, projectId, commonFloor);
            if (loadPublicOrder != null) {
                String PublicNaturalFloor=null;
                if ("x".equals(loadPublicOrder)) {
                    PublicNaturalFloor="x";
                }else {
                    // 查询出权限标识natural_floor
                    PublicNaturalFloor = iAppProjectDao.getNaturalFloor(deviceUnique, loadPublicOrder);
                }

                //查询用户常用公共楼层
                String publicFloor = iAppProjectDao.getPublicFloor(userId, projectId);

                Map<String, String> publicFloorMap;
                if (StringUtils.isNotBlank(publicFloor)) {
                    publicFloorMap = JSON.parseObject(publicFloor, HashMap.class);
                } else {
                    publicFloorMap = new HashMap<>();
                }
                publicFloorMap.put(deviceUnique, PublicNaturalFloor);
                publicFloor = JSON.toJSONString(publicFloorMap);
                iAppProjectDao.updatePublicFloor(userId, projectId, publicFloor);
            }
        }

        return 1;
    }

    /**
     * <desc>
     * 自动切换小区
     * </desc>
     *
     * @param longitude 经度
     * @param latitude  纬度
     * @param userId    用户id
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/10/11
     */
    @Override
    public Map<String, Object> autoMatchProject(String longitude, String latitude, String userId) throws Exception {
        List<Map<String, Object>> positionMapList = iAppProjectDao.getUserProjectPosition(userId);
        Map<String, Object> data = new HashMap<>();
        Map<String, Object> userProjectMap = new HashMap<>();
        if (positionMapList != null && !positionMapList.isEmpty()) {
            double lng1 = Double.parseDouble(longitude);
            double lat1 = Double.parseDouble(latitude);
            for (Map<String, Object> positionMap : positionMapList) {
                // 用户在项目上无迁入状态的房间且无有效的用户-设备权限记录，则此项目不做展示
                userProjectMap.put("projectId", positionMap.get("projectId"));
                Integer userInProjectExistRoom = iAppProjectDao.countUserRoomInProject(userProjectMap);
                if (!(userInProjectExistRoom != null && userInProjectExistRoom > 0)) {
                    Integer countUserAuthInFloor = iAppProjectDao.countUserAuthInFloor(userProjectMap);
                    Integer countUserAuthInDoor = iAppProjectDao.countUserAuthInDoor(userProjectMap);
                    Integer countUserAuthInCloudDoor = iAppProjectDao.countUserAuthInCloudDoor(userProjectMap);
                    if (!((countUserAuthInFloor + countUserAuthInDoor + countUserAuthInCloudDoor) > 0)) {
                        continue;
                    }
                }
                String position = positionMap.get("position").toString();
                if (StringUtils.isBlank(position)) {
                    continue;
                }
                String[] positionArr = StringHandlerUtil.splitString(position);
                if (positionArr.length != 2) {
                    continue;
                }
                double lng2 = Double.parseDouble(positionArr[0]);
                double lat2 = Double.parseDouble(positionArr[1]);
                // 计算两点直线距离
                double distance = LocationUtil.getDistance(lat1, lng1, lat2, lng2);
                // 满足小于1km，且data中没有值或比data中的小区距离更近，则替换
                if (distance < 1000 && (data.isEmpty() || distance < Double.parseDouble(data.get("distance").toString()))) {
                    data.put("projectId", positionMap.get("projectId"));
                    data.put("projectName", positionMap.get("projectName"));
                    data.put("distance", distance);
                }
            }
        }
        data.remove("distance");
        return data;
    }


    /**
     * <desc>
     * 获取用户当前项目下的推送消息包括运营+物业
     * </desc>
     *
     * @return 当前项目下的推送消息
     * @author JuGuang.S
     * @createDate 2018/09/17
     */
    @Override
    public Map<String, Object> getMessageBoxByPropertyAndOperate(String projectId, String pageNum, String userId, String url) throws Exception {
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        params.put("projectId", projectId);
        params.put("userId", userId);
        // 分页索引
        if (Integer.parseInt(pageNum) > 0) {
            params.put("startSlip", (Integer.parseInt(pageNum) - 1) * 15);
        } else {
            params.put("startSlip", 0);
        }
        // 分页记录数
        params.put("pageSize", 15);
        // 消息类型
        params.put("propertyType", 5);
        Integer unReadCount = 0;
        // 1.8.5版本先注掉，1.8.6合并代码后打开注释
        unReadCount = iAppProjectDao.getPropertyAndOperatePushCount(params);
        // 未读小区通知条数，暂无，为0
        data.put("unReadCount", unReadCount.toString());
        // 当前只有缴费通知
        List<AppMessageBoxVO> msgAry = null;

        // 小区通知
        // 计算总页数
        Integer allCount = iAppProjectDao.getAllPropertyAndOperatePushCount(params);
        data.put("totalNum", allCount % 15 == 0 ? allCount / 15 : allCount / 15 + 1);
        msgAry = iAppProjectDao.getPropertyAndOperatePushPage(params);

        // 消息分页数据
        if (msgAry == null) {
            data.put("msgAry", new ArrayList<>());
        } else {
            for (AppMessageBoxVO messageBoxVO : msgAry) {
                messageBoxVO.setUrl(url + "pushInfoId=" + messageBoxVO.getMsgId());
            }
            data.put("msgAry", msgAry);
        }
        return data;
    }

    /**
     * <desc>
     * 检测项目是否开启蓝牙进场呼梯配置
     * </desc>
     *
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2020/04/27
     */
    public Integer checkProjectBlueToothCall(String projectId) {
        return iAppProjectDao.checkProjectBlueToothCall(projectId);
    }

    /**
     * <desc>
     * 根据定位获取最近的开通了游客模式的项目
     * </desc>
     *
     * @return 项目信息
     * @author wangzhi
     * @createDate 2020/04/30
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Map<String, Object> getProjectByLocation(AppTouristDTO appTouristDTO) throws Exception {
        List<String> positionList = StringHandlerUtil.splitStringList(appTouristDTO.getPosition());
        String longitude = positionList.get(0);
        String latitude = positionList.get(1);
        List<Map<String, Object>> positionMapList = iAppProjectDao.getAllProjectHasPositionAndGuest();
        Map<String, Object> data = new HashMap<>();
        if (positionMapList != null && !positionMapList.isEmpty()) {
            double lng1 = Double.parseDouble(longitude);
            double lat1 = Double.parseDouble(latitude);
            for (Map<String, Object> positionMap : positionMapList) {
                String positionData = positionMap.get("position").toString();
                if (StringUtils.isBlank(positionData)) {
                    continue;
                }
                String[] positionArr = StringHandlerUtil.splitString(positionData);
                if (positionArr.length != 2) {
                    continue;
                }
                double lng2 = Double.parseDouble(positionArr[0]);
                double lat2 = Double.parseDouble(positionArr[1]);
                // 计算两点直线距离
                double distance = LocationUtil.getDistance(lat1, lng1, lat2, lng2);
                // 满足小于1km，且data中没有值或比data中的小区距离更近，则替换
                if (distance < 1000 && (data.isEmpty() || distance < Double.parseDouble(data.get("distance").toString()))) {
                    data.put("projectId", positionMap.get("projectId"));
                    data.put("projectName", positionMap.get("projectName"));
                    data.put("distance", distance);
                    data.put("pubKey", positionMap.get("pubKey"));
                    data.put("isFaceRecognition", positionMap.get("isFaceRecognition"));
                    data.put("bluetoothCall", positionMap.get("bluetoothCall"));
                    data.put("province", positionMap.get("province"));
                    data.put("cityName", positionMap.get("cityName"));
                    data.put("cityId", positionMap.get("cityId"));
                }
            }
        }
        data.remove("distance");
        return data;
    }

    /**
     * <desc>
     *      获取项目远程开门配置
     * </desc>
     *
     * @param projectId
     * @return
     * @author Juguang.S
     * @createDate 2020/09/17
     */
    public Integer getNetworkOpenSetting(String projectId){
        return iAppProjectDao.getNetworkOpenSetting(projectId);
    }

    /**
     * <desc>
     *      保存用户项目信息
     * </desc>
     *
     * @param appGetProjectDTO 选择项目参数DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/6
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer saveUserProject(AppGetProjectDTO appGetProjectDTO) throws Exception {

        //添加用户项目之前判断该用户之前是否有该项目
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(appGetProjectDTO);
        if (iAppProjectDao.getUserProjectCount(params) > 0){
            return 0;
        }

        Date nowTime = new Date();
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setUserId(appGetProjectDTO.getUserId());
        appUserProjectPO.setProjectId(appGetProjectDTO.getProjectId());
        appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        appUserProjectPO.setDataSource(DATA_SOURCE);
        appUserProjectPO.setCreateTime(nowTime);
        appUserProjectPO.setUpdateTime(nowTime);
        if (iAppProjectDao.save(SqlUtil.durableData(appUserProjectPO, PlatformConstants.TABLE_SAVE)) >0){
            return 1;
        }
        return 0;
    }

    /**
     * <desc>
     *      模糊查询项目
     * </desc>
     *
     * @param projectName 项目名称
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/6
     */
    @Override
    public List<Map<String, Object>> getProjectByProjectName(String projectName) throws Exception {
        return iAppProjectDao.getProjectByProjectName(projectName);
    }

    /**
     * <desc>
     *      删除用户项目传参DTO
     * </desc>
     *
     * @param appGetProjectDTO 删除用户项目传参DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/7
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public MessageVO deleteUserProject(AppGetProjectDTO appGetProjectDTO) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", appGetProjectDTO.getUserId());
        params.put("projectId", appGetProjectDTO.getProjectId());
        //查看该用户在该项目下是否有房屋，即是否进行了房屋认证
        Integer roomCount = iAppProjectDao.getUserRoomCount(params);
        if (roomCount > 0){
            return new MessageVO(AppErrorCodeEnum.USER_HAVE_PROJECT_ROOM_ERROR.getErrorCode());
        }
        //查看该设备是否有电梯、门禁、云对讲的权限
        Integer deviceAuthCount = iAppProjectDao.getUserDeviceAuthCount(params);
        if (deviceAuthCount > 0){
            return new MessageVO(AppErrorCodeEnum.USER_HAVE_PROJECT_DEVICE_AUTH_ERROR.getErrorCode());
        }

        //删除操作
        params.put("updateTime", new Date());
        if (iAppProjectDao.deleteUserProject(params) >0){
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }
        return new MessageVO(AppErrorCodeEnum.USER_HAVE_NO_PROJECT_OR_BEEN_DELETED_ERROR.getErrorCode());
    }

    /**
     * <desc>
     *      获取项目下的用户类型id和用户类型名称
     * </desc>
     *
     * @param roomId 房间号
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/17
     */
    @Override
    public List<Map<String, Object>> getProjectRoleList(String roomId) throws Exception {
        String projectId= iAppProjectDao.getProjectByRoomId(roomId);
        return iAppProjectDao.getProjectRoleList(projectId);
    }

    /**
     * <desc>
     *      获取项目下的用户类型id和用户类型名称
     * </desc>
     *
     * @param projectId 项目id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/17
     */
    @Override
    public List<Map<String, Object>> getProjectUserRoleList(String projectId) throws Exception {
        List<Map<String, Object>> userRoleList = iAppProjectDao.getProjectUserRoleList(projectId);
        Map<String, Object> visitorMap = new HashMap<>();
        visitorMap.put("roleId", VISITOR_TYPE);
        visitorMap.put("roleName", VISITOR_NAME);
        userRoleList.add(visitorMap);
        return userRoleList;
    }

    /**
     * <desc>
     *      获取项目下的用户类型id和用户类型名称
     * </desc>
     *
     * @param projectId 项目id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/17
     */
    @Override
    public List<Map<String, Object>> getProjectRoleListByProjectId(String projectId) throws Exception {
        return iAppProjectDao.getProjectRoleList(projectId);
    }
}
